﻿using System;
using System.Collections.Generic;
using WCFCommon;
using frag_boardgame;

namespace WCFConsoleUI
{
    public static class ConsoleUI
    {
        public static LobbyMenu lobbyMenu;
        public static RoomMenu roomMenu;


        public static void Error(string text)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            WriteLine(text);
            Console.ForegroundColor = ConsoleColor.Gray;
        }
        public static string GetValue(string text)
        {
            WriteLine(text);
            return Console.ReadLine();
        }
        public static string GetServerAddress()
        {
            ServersMenu servers = new ServersMenu();
            servers.setTitle("Please choose one of the following servers to connect to:");
            servers.createMenu();
            servers.drawMenu();
            string read = Console.ReadLine();
            int temp;
            if (int.TryParse(read, out temp))
            {
                if (temp == 1)
                    return "frag-boardgame.kicks-ass.org";
                else if (temp == 2)
                    return "localhost";
            }
            
            return read;
        }
        public static string GetName()
        {
            string name = "";
            while (name == "")
            {
                name=GetValue("Please enter your name: ");
                if (name == "")
                    Error("No name was entered!");
            }

            return name;
        }

        private static string GetHiddenValue(String message)
        {
            WriteLine(message);
            Stack<string> passbits = new Stack<string>();
            //keep reading
            for (ConsoleKeyInfo cki = Console.ReadKey(true); cki.Key != ConsoleKey.Enter; cki = Console.ReadKey(true))
            {
                if ((cki.Key == ConsoleKey.Backspace))
                {
                    //rollback the cursor and write a space so it looks backspaced to the user
                    if (Console.CursorLeft > 0)
                    {
                        Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                        Console.Write(" ");
                        Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                        passbits.Pop();
                    }
                }

                else
                {
                    Console.Write("*");
                    passbits.Push(cki.KeyChar.ToString());

                }
            }
            string[] pass = passbits.ToArray();
            Array.Reverse(pass);
            WriteLine("");
            return string.Join(string.Empty, pass);
        }

        public static string GetPassword()
        {
            string password = "";
            while (password == "")
            {
                password = GetHiddenValue("Please enter your password: ");
                if (password == "")
                    Error("No password was entered!");
            }

            return password;




        }
        public static string ConfirmPassword()
        {
            return GetHiddenValue("Please confirm your password: ");
        }

        public static string GetEmail()
        {
            return GetValue("Please enter your email address: ");
        }

        public static LoginOptions GetLoginCommand()
        {
            LoginMenu menu = new LoginMenu();
            menu.createMenu();
            menu.setTitle("What woul'd you like to do?");
            menu.drawMenu();

            while (true)
            {
                string read = Console.ReadLine();
                int temp;
                if (int.TryParse(read, out temp))
                {
                    if (temp == 1)
                        return LoginOptions.Exist;
                    else if (temp == 2)
                        return LoginOptions.New;
                    else if (temp == 3)
                        return LoginOptions.Guest;
                }
            }

        }

        public static LobbyOptions GetLobbyCommand(out string roomName)
        {
            roomName = "";
            while (true)
            {
                string[] command = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                try
                {
                    string cmd = command[0];

                    if (cmd == "v")
                        return LobbyOptions.PrintRooms;
                    else if (cmd == "c")
                    {
                        roomName = command[1];
                        return LobbyOptions.Create;
                    }
                    else if (cmd == "j")
                    {
                        roomName = command[1];
                        return LobbyOptions.Join;
                    }
                    else if (cmd == "h")
                        return LobbyOptions.Help;
                    else if (cmd == "q")
                        return LobbyOptions.Quit;
                    else if (cmd == "s")
                        return LobbyOptions.Score;
                    else if (cmd == "history")
                        return LobbyOptions.History;

                    else
                        Error("Invalid Operation");
                }
                catch { }
            
         
                
            }
        }


        public static void InitilzeLobbyMenu(string userName)
        {
            lobbyMenu = new LobbyMenu();
            lobbyMenu.setTitle("Hi " + userName + "! Welcome to the \"Frag\" game lobby! Please choose:");
            lobbyMenu.createMenu();
            
        }

        public static void DrawLobby()
        {
            lobbyMenu.drawMenu();
        }

        public static void InitilzeRoomMenu(string roomName)
        {
            roomMenu = new RoomMenu();
            roomMenu.setTitle("Welcome to " + roomName);
            roomMenu.createMenu();
            
        }

        public static void DrawRoom()
        {
            roomMenu.drawMenu();
        }

       
        public static void printPlayers(Dictionary<string,int> users)
        {
            WriteLine("");
            int count = 1;
            foreach (string name in users.Keys)
            {
                WriteLine(count + ". " + name + ".  Score: " + users[name]);               
                count++;
            }
            

            WriteLine("");

        }

        public static void WriteLine(string text)
        {
            ConsoleLib.ConsoleUI.WriteToConsole(text);
        }
        public static void printRooms(RoomInfo[] rooms)
        {
            

            WriteLine("Name\tPlayers\tBoard");
           WriteLine("====\t=======\t=====");
            foreach (RoomInfo room in rooms)
            {
                WriteLine(String.Format("{0}\t{1}/{2}\t{3}x{4}", room.name, room.nPlayers, room.config.NumberOfPlayers, room.config.Rows, room.config.Cols));
            }

           WriteLine("");
        }

        public static RoomOptions GetRoomCommand(out string message)
        {
            message = "";
            while (true)
            {
         
                string command = Console.ReadLine();
                if (command.StartsWith("say "))
                {
                    message = command.Substring((4));
                    return RoomOptions.Say;
                }
                else if (command.StartsWith("start"))
                {
                    return RoomOptions.Start;
                }
                else if (command.StartsWith(("q")))
                {
                    return RoomOptions.Quit;
                }
                else if (command.StartsWith("v"))
                {
                    return RoomOptions.PrintPlayers;
                }
                else if (command.StartsWith("wait"))
                {
                    return RoomOptions.Wait;
                }
                else
                    Error("Invalid operation");
            }

        }


        public static GameConfiguration GetConfiguration()
        {


            return ConsoleLib.ConsoleUI.GetConfiguration();

        }

        public static void SetLastLine(string text)
        {
            ConsoleLib.ConsoleUI.SetLastMessage(text);
        }
        public static void PrintBoard(Board board)
        {
            ConsoleLib.ConsoleUI.PrintBoard(board);
        }

        public static void PrintValues(GameData data)
        {
            ConsoleLib.ConsoleUI.PrintValues(data);
        }

        public static void PrintHistory(String[] history)
        {
            if (history.Length == 0)
            {
                WriteLine("");
                WriteLine("you dont have history");
                WriteLine("");
                return;
            }
            
            WriteLine("");
            WriteLine("Player's Games History");
            WriteLine("----------------------");
            foreach (String str in history)
            {
                WriteLine(str);
            }
            WriteLine("");
        }

        public static void PrintScore(int score)
        {
            WriteLine("Your score is: " + score);
        }

        public static GameOptions GetGameCommand(out int val,out Direction direction)
        {
            val = -1;
            direction = Direction.Up;
            
            
           
            
                
            while (true)
            {





                string command = Console.ReadLine();
    
                if (command.StartsWith("undo"))
                {
                    return GameOptions.Undo;
                }
                else if (command.StartsWith("redo"))
                {
                    return GameOptions.Redo;
                }
                else if ((command.Length > 1) && (!int.TryParse(command.Substring(1), out val)))
                {
                    continue;
                }

                if (command.StartsWith("u"))
                {
                    return GameOptions.Move;
                }
                else if (command.StartsWith("d"))
                {
                    direction = Direction.Down;
                    return GameOptions.Move;
                }
                else if (command.StartsWith("l"))
                {
                    direction = Direction.Left;
                    return GameOptions.Move;
                }
                else if (command.StartsWith("r"))
                {
                    direction = Direction.Right;
                    return GameOptions.Move;
                }
                else if (command.StartsWith("s"))
                {
                    return GameOptions.Shoot;
                }
                else if (command.StartsWith("f"))
                {
                    return GameOptions.Finish;
                }

                else
                    Error("Invalid Operation!");
            }

            


        }
        public static void PrintBoardsList(String[] boards)
        {

            WriteLine("");
            if (boards.Length == 0)
            {
                WriteLine("");
                return;
            }
            
            WriteLine("You can use the following boards:");
            foreach (string str in boards)
            {
                WriteLine("\t" + str);
            }
            WriteLine("");
        }
    }
}



